package retrieval;

import java.awt.Font;
import java.awt.List;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.Document;

import preprocess.XmlTransfer;
import utils.ObjectPersistence;

public class QueryFrame extends JInternalFrame implements ActionListener,
        ItemListener
{
    /**
     * 
     */
    private static final long        serialVersionUID  = 7435465754529767858L;
    private JPanel                   jContentPane1     = null;
    private JButton                  registerButton    = null;
    private JTextArea                showMessage       = null;
    private List                     list              = null;
    private JTextField               register          = null;
    private JLabel                   message           = null;
    private JLabel                   Keywordsresult    = null;
    private JButton                  startButton       = null;
    private JButton                  stopButton        = null;
    public CreateDAGBKI              createDAGBKI      = new CreateDAGBKI();
    public boolean                   isLast            = false;
    public boolean                   sem               = true;
    public boolean                   sep1              = true;
    public boolean                   sep2              = true;
    public boolean                   sep3              = false;
    public int                       num               = 0;
    private List                     list1             = null;
    private JLabel                   Fileslabel        = null;
    private JButton                  fileChooserButton = null;
    private JComboBox                fileJComboBox     = null;
    public HashMap<String, Document> fileList          = new HashMap<String, Document>();
    public HashMap<String, Integer>  similarityMap     = new HashMap<String, Integer>();
    public int                       method            = SearchSimiXMLDoc.VSM;

    /**
     * This is the default constructor
     * 
     * @throws ClassNotFoundException
     * @throws IOException
     * @throws FileNotFoundException
     */
    public QueryFrame()
    {
        super("", true, false, true, true);
        initialize();
        setVisible(true);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
    }

    /**
     * This method initializes this
     * 
     * @return void
     * @throws ClassNotFoundException
     * @throws IOException
     * @throws FileNotFoundException
     */
    private void initialize()
    {
        this.setSize(744, 449);
        setContentPane(getJContentPane1());
        setTitle("XML流查询窗口");

        File dag = new File("keywordSet.dag");
        if (dag.exists())
        {
            ObjectPersistence<Hashtable<String, QueryInfo>> op1 = new ObjectPersistence<Hashtable<String, QueryInfo>>();
            ObjectPersistence<Hashtable<String, HashSet<String>>> op2 = new ObjectPersistence<Hashtable<String, HashSet<String>>>();
            ObjectPersistence<HashSet<String>> op3 = new ObjectPersistence<HashSet<String>>();

            try
            {
                CreateDAGBKI.queryList = op1.load(new File("queryList.dag"));
                CreateDAGBKI.keyword2query = op2.load(new File(
                        "keyword2query.dag"));
                CreateDAGBKI.query2parents = op2.load(new File(
                        "query2parents.dag"));
                CreateDAGBKI.parents2query = op2.load(new File(
                        "parents2query.dag"));
                CreateDAGBKI.uselessNodeList = op2.load(new File(
                        "uselessNodeList.dag"));
                CreateDAGBKI.keywordSet = op3.load(dag);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * This method initializes jContentPane1
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane1()
    {
        if (jContentPane1 == null)
        {
            Fileslabel = new JLabel();
            Fileslabel.setBounds(new Rectangle(573, 52, 95, 23));
            Fileslabel.setText("File Result");
            // Fileslabel.setHorizontalAlignment(Label.CENTER);
            Keywordsresult = new JLabel();
            Keywordsresult.setBounds(new Rectangle(314, 50, 119, 23));
            Keywordsresult.setText("Keywords Result");
            // Keywordsresult.setHorizontalAlignment(Label.CENTER);
            message = new JLabel();
            message.setBounds(new Rectangle(39, 48, 191, 23));
            message.setText("ShowMessage");
            // message.setHorizontalAlignment(Label.CENTER);
            jContentPane1 = new JPanel();
            jContentPane1.setLayout(null);
            jContentPane1.add(getRegisterButton(), null);
            jContentPane1.add(getShowMessage(), null);
            jContentPane1.add(getList(), null);
            jContentPane1.add(getRegister(), null);
            jContentPane1.add(message, null);
            jContentPane1.add(Keywordsresult, null);
            jContentPane1.add(getStartButton(), null);
            jContentPane1.add(getStopButton(), null);
            jContentPane1.add(getList1(), null);
            jContentPane1.add(Fileslabel, null);
            jContentPane1.add(getFileChooserButton(), null);
            jContentPane1.add(getFileJComboBox(), null);

        }
        return jContentPane1;
    }

    /**
     * This method initializes registerButton
     * 
     * @return java.awt.Button
     */
    private JButton getRegisterButton()
    {
        if (registerButton == null)
        {
            registerButton = new JButton();
            registerButton.setBounds(new Rectangle(295, 15, 76, 23));
            registerButton.setText("Register");
            registerButton.addActionListener(this);
            registerButton.setActionCommand("registerButton");
        }
        return registerButton;
    }

    /**
     * This method initializes showMessage
     * 
     * @return java.awt.TextArea
     */
    private JTextArea getShowMessage()
    {
        if (showMessage == null)
        {
            showMessage = new JTextArea();
            showMessage.setBounds(new Rectangle(16, 77, 237, 282));
            showMessage.setEditable(false);

        }
        return showMessage;
    }

    /**
     * This method initializes list
     * 
     * @return java.awt.List
     */
    private List getList()
    {
        if (list == null)
        {
            list = new List();
            list.setMultipleMode(false);
            list.setBounds(new Rectangle(263, 78, 236, 283));
            list.addItemListener(this);
        }
        return list;
    }

    /**
     * This method initializes register
     * 
     * @return java.awt.TextField
     */
    private JTextField getRegister()
    {
        if (register == null)
        {
            register = new JTextField();
            register.setBounds(new Rectangle(13, 12, 268, 28));
        }
        return register;
    }

    /**
     * This method initializes startButton
     * 
     * @return java.awt.Button
     */
    private JButton getStartButton()
    {
        if (startButton == null)
        {
            startButton = new JButton();
            startButton.setBounds(new Rectangle(137, 380, 85, 23));
            startButton.setText("QUERY");
            startButton.addActionListener(this);
            startButton.setActionCommand("startButton");
        }
        return startButton;
    }

    /**
     * This method initializes stopButton
     * 
     * @return java.awt.Button
     */
    private JButton getStopButton()
    {
        if (stopButton == null)
        {
            stopButton = new JButton();
            stopButton.setBounds(new Rectangle(283, 379, 91, 23));
            stopButton.setText("STOP");
            stopButton.addActionListener(this);
            stopButton.setActionCommand("stopButton");

        }
        return stopButton;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        String tmp = e.getActionCommand();
        if (tmp.equals("registerButton"))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    sep3 = true;
                    while (true)
                    {
                        if ((!sem) && (!sep2))
                        {
                            showMessage.append("Query is ing!\r\n");
                            continue;
                        }
                        String query = register.getText().toString();
                        if (!query.isEmpty())
                        {
                            createDAGBKI.insertQueryToGraph(query);
                            if ((isLast && sep1) || sep2)
                            {
                                sem = false;
                            }
                            sep3 = false;
                            showMessage.append("Insert is done!\r\n");
                            break;
                        }
                    }
                }
            }.start();
        }
        // final Main main = this;
        if (tmp.equals("startButton"))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        sep2 = false;
                        isLast = true;
                        num = 0;
                        String tmp = "";
                        SAXParserFactory spfactory = SAXParserFactory
                                .newInstance();
                        SAXParser parser = spfactory.newSAXParser();
                        while (isLast)
                        {
                            if (XmlTransfer.xmlList.isEmpty())
                            {
                                try
                                {
                                    sleep(1000);
                                }
                                catch (Exception e2)
                                {}
                                continue;
                            }
                            byte[] currentByte = new byte[(XmlTransfer.xmlList
                                    .get(num)).length];
                            int index = 0;
                            for (byte b : XmlTransfer.xmlList.get(num))
                            {
                                currentByte[index] = b;
                                index++;
                            }
                            String xmlName = XmlTransfer.xmlNameList.get(num);
                            if (xmlName.equals(tmp))
                            {
                                try
                                {
                                    sleep(1000);
                                }
                                catch (Exception e2)
                                {}
                                showMessage
                                        .append("Waiting for new xml source.\r\n");
                                continue;
                            }
                            if (sem && sep3)
                            {
                                showMessage.append("Insert is ing!\r\n");
                                continue;
                            }
                            showMessage.append("xml file:" + xmlName
                                    + " has come.\r\n");
                            ByteArrayInputStream xmlStr = new ByteArrayInputStream(
                                    currentByte);
                            QueryOnDAGBKI queryOnDAGBKI = new QueryOnDAGBKI(
                                    xmlName);
                            parser.parse(xmlStr, queryOnDAGBKI);
                            list.add("****Query results for " + xmlName
                                    + "****");
                            Set<String> queryName = CreateDAGBKI.queryResult
                                    .keySet();
                            for (String query : queryName)
                            {
                                if (CreateDAGBKI.queryResult.get(query)
                                        .containsKey(xmlName))
                                {
                                    list.add(query + ":" + xmlName);
                                }
                            }
                            sem = true;
                            showMessage.append("Query for " + xmlName
                                    + " is done!\r\n");
                            tmp = xmlName;
                            // StreamWrapper.save(currentByte, xmlName);
                            if (XmlTransfer.isEnd)
                            {
                                num++;
                                System.out.println(Integer.toString(num));
                                if (num == XmlTransfer.size)
                                {
                                    showMessage
                                            .append("xml stream is over.\r\n");
                                    break;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    catch (Exception e1)
                    {
                        e1.printStackTrace();
                    }
                }
            }.start();
        }
        if (tmp.equals("stopButton"))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    isLast = false;
                    sep1 = false;
                }
            }.start();
        }
        if (tmp.equals("getFileChooserButton"))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    list1.removeAll();
                    fileList = new HashMap<String, Document>();
                    File selectedFile = null;
                    JFileChooser chooser = new JFileChooser();
                    chooser.setFont(new Font("\u5b8b\u4f53", Font.PLAIN, 14));
                    chooser.setFileFilter(new FileFilter()
                    {
                        @Override
                        public boolean accept(File f)
                        {
                            return f.getName().toLowerCase().endsWith(".xml")
                                    || f.isDirectory();
                        }

                        @Override
                        public String getDescription()
                        {
                            return "*.xml";
                        }
                    });
                    int result = chooser.showOpenDialog(null);
                    if (result == JFileChooser.APPROVE_OPTION)
                    {
                        selectedFile = chooser.getSelectedFile();
                    }
                    if (selectedFile != null)
                    {
                        SearchSimiXMLDoc searcher = SearchSimiXMLDoc
                                .getInstance();
                        fileList = searcher.search(selectedFile, method);
                        Set<String> xmlName = fileList.keySet();
                        for (String eachXml : xmlName)
                        {
                            list1.add(eachXml);
                        }
                    }
                }
            }.start();
        }

    }

    @Override
    public void itemStateChanged(ItemEvent e)
    {
        if (e.getSource().equals(list))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        String query[] = list.getSelectedItem().toString()
                                .split(":");
                        XRetrievalTreeGenerator treeGenerator = new XRetrievalTreeGenerator();
                        if (CreateDAGBKI.queryResult.get(query[0]) != null)
                        {
                            Set<Document> set = CreateDAGBKI.queryResult.get(
                                    query[0]).get(query[1]);
                            for (Object doc : set)
                            {
                                treeGenerator.display((Document) doc);
                            }
                        }
                    }
                    catch (IOException e1)
                    {
                        e1.printStackTrace();
                    }
                }
            }.start();
        }
        if (e.getSource().equals(list1))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        String file = list1.getSelectedItem().toString();
                        XRetrievalTreeGenerator treeGenerator = new XRetrievalTreeGenerator();
                        treeGenerator.display(fileList.get(file));
                    }
                    catch (IOException e1)
                    {
                        e1.printStackTrace();
                    }
                }
            }.start();
        }
        if (e.getSource().equals(fileJComboBox))
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    String str = fileJComboBox.getSelectedItem().toString();
                    method = similarityMap.get(str);
                }
            }.start();
        }
    }

    /**
     * This method initializes list1
     * 
     * @return java.awt.List
     */
    private List getList1()
    {
        if (list1 == null)
        {
            list1 = new List();
            list1.setBounds(new Rectangle(508, 79, 214, 280));
            list1.addItemListener(this);
        }
        return list1;
    }

    /**
     * This method initializes fileChooserButton
     * 
     * @return java.awt.Button
     */
    private JButton getFileChooserButton()
    {
        if (fileChooserButton == null)
        {
            fileChooserButton = new JButton();
            fileChooserButton.setBounds(new Rectangle(510, 14, 98, 22));
            fileChooserButton.setText("Choose File");
            fileChooserButton.addActionListener(this);
            fileChooserButton.setActionCommand("getFileChooserButton");
        }
        return fileChooserButton;
    }

    private JComboBox getFileJComboBox()
    {
        if (fileJComboBox == null)
        {
            similarityMap.put("VSM", SearchSimiXMLDoc.VSM);
            similarityMap.put("TED", SearchSimiXMLDoc.TED);
            similarityMap.put("SLVM", SearchSimiXMLDoc.SLVM);
            fileJComboBox = new JComboBox();
            fileJComboBox.setBounds(new Rectangle(628, 14, 88, 22));
            fileJComboBox.addItemListener(this);
            Set<String> set = similarityMap.keySet();
            for (String str : set)
            {
                fileJComboBox.addItem(str);
            }
        }
        return fileJComboBox;
    }
} // @jve:decl-index=0:visual-constraint="42,3"
